package Beans;

import frame.MainFrame;

import java.util.ArrayList;
import java.util.List;

public class StorageMethods {
    /**
    * @Description: 创建一个主内存空间
    * @Param: [fullStorage]
    * @return: Beans.MainMemory[]
    * @Author: PY
    * @Date: 2021/11/26
    */
    public static MainMemory[] createStorage(int fullStorage){
        MainMemory[] mainStorages = new MainMemory[fullStorage];
        for (int i = 0; i < fullStorage; i++) {
            mainStorages[i] = new MainMemory();
        }
        return mainStorages;
    }

    /**
    * @Description: 获取可用内存表
    * @Param: [mainMemories]
    * @return: java.util.List<Beans.MemoryList>
    * @Author: PY
    * @Date: 2021/11/26
    */
    public static List<MemoryList> getMemoryList(MainMemory[] mainMemories){
        List<MemoryList> memoryList = new ArrayList<MemoryList>();
        MemoryList memory = new MemoryList();
        for (int i = 0; i < mainMemories.length-1; i++) {
            if(!mainMemories[i].isUsed&&i==0){
                memory = new MemoryList();
                memory.setStartAddress(i);
                memory.setMemorySize(1);
            }
            if(mainMemories[i].isUsed&&!mainMemories[i+1].isUsed){
                memory = new MemoryList();
                memory.setStartAddress(i + 1);
                memory.setMemorySize(1);
            }
            if(!mainMemories[i].isUsed&&!mainMemories[i+1].isUsed){
                memory.setMemorySize(memory.getMemorySize()+1);
            }
            if(!mainMemories[i].isUsed&&mainMemories[i+1].isUsed){
                memoryList.add(memory);
            }
            if(!mainMemories[i].isUsed&&i+1==mainMemories.length-1){
                memoryList.add(memory);
            }
        }
        return memoryList;
    }
    /**
    * @Description: 将进程插入内存
    * @Param: [workingPCB, mainMemories]
    * @return: boolean
    * @Author: PY
    * @Date: 2021/11/26
    */
    public static boolean insertToMemory(PCB workingPCB,MainMemory[] mainMemories){ //正在改
        boolean Success = false;
        int totalFreeMemory = getTotalFreeMemory(mainMemories);
        List<MemoryList> memoryList = getMemoryList(mainMemories);
        for(MemoryList memory:memoryList){
            if(memory.getMemorySize() >= workingPCB.getStorageRequierd()){
                workingPCB.setStorageStart(memory.getStartAddress());
                Success = true;
                break;
            }
        }
        if(!Success&&totalFreeMemory>=workingPCB.getStorageRequierd()){
            alignMemory(mainMemories);
            List<MemoryList> memoryList1 = getMemoryList(mainMemories);
            for(MemoryList memory:memoryList1){
                if(memory.getMemorySize() >= workingPCB.getStorageRequierd()){
                    workingPCB.setStorageStart(memory.getStartAddress());
                    Success = true;
                    break;
                }
            }
        }
        if(Success){
            for(int i = 0;i<workingPCB.getStorageRequierd();i++){
                mainMemories[workingPCB.getStorageStart()+i].isUsed = true;
                mainMemories[workingPCB.getStorageStart()+i].setProcessStored(workingPCB);
            }
        }
        return Success;
    }

    /**
    * @Description: 将进程移除出内存
    * @Param: [runningPCB, mainMemories]
    * @return: void
    * @Author: PY
    * @Date: 2021/11/26
    */
    public static void removeFromMemory(PCB runningPCB,MainMemory[] mainMemories){
        for(int i = runningPCB.getStorageStart();i < runningPCB.getStorageStart()+runningPCB.getStorageRequierd();i++){
            mainMemories[i].isUsed = false;
            mainMemories[i].setProcessStored(null);
        }
        MainFrame.getMemoryData(MainFrame.memoryTable, MainFrame.mainMemories);
    }

    /**
    * @Description: 内存紧缩
    * @Param: [mainMemories]
    * @return: void
    * @Author: PY
    * @Date: 2021/11/26
    */
    public static void alignMemory(MainMemory[] mainMemories){
        List<PCB> pcbList = new ArrayList<>();
        PCB tempPCB = null;
        for(int i = 0;i<mainMemories.length;i++){
            if(mainMemories[i].isUsed&&tempPCB != mainMemories[i].getProcessStored()){
                tempPCB = mainMemories[i].getProcessStored();
                pcbList.add(tempPCB);
            }
        }
        for(PCB pcb : pcbList){
            List<MemoryList> memoryList = getMemoryList(mainMemories);
            MemoryList tempMemoryList = memoryList.get(0);
            if(pcb.getStorageStart()!=0) {
                if(!mainMemories[pcb.getStorageStart()-1].isUsed) {
                    for (int i = 0; i < pcb.getStorageRequierd(); i++) {
                        mainMemories[tempMemoryList.getStartAddress()+i].isUsed=true;
                        mainMemories[tempMemoryList.getStartAddress()+i].setProcessStored(pcb);
                        mainMemories[pcb.getStorageStart()+i].isUsed=false;
                        mainMemories[pcb.getStorageStart()+i].setProcessStored(null);
                    }
                }
            }
        }
        MainFrame.getMemoryData(MainFrame.memoryTable,MainFrame.mainMemories);
    }

    /**
    * @Description: 获取主内存中所剩的所有内存空间大小
    * @Param: [mainMemories]
    * @return: int
    * @Author: PY
    * @Date: 2021/11/26
    */
    public static int getTotalFreeMemory(MainMemory[] mainMemories){
        int totalFreeMemory = 0;
        List<MemoryList> memoryList = getMemoryList(mainMemories);
        for(MemoryList memory : memoryList){
            totalFreeMemory = totalFreeMemory+memory.getMemorySize();
        }
        return totalFreeMemory;
    }
}